home *** CD-ROM | disk | FTP | other *** search
Text File | 2001-03-19 | 38.1 KB | 2,024 lines |
- ;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
- * $Id: dos.s 1.1 1999/02/03 04:09:58 jotd Exp $
- **************************************************************************
- * DOS-LIBRARY *
- **************************************************************************
-
- ; structure for custom filehandle
-
- FH_ALLOCLEN = 0
- FH_PORT = 4 ; exact DOS offset in FileHandle structure
- FH_TYPE = 8 ; exact DOS offset in FileHandle structure
- FH_OPENMODE = $C
- FH_CURRENTPOS = $10 ; exact DOS offset in FileHandle structure
- FH_FILELEN = $14 ; exact DOS offset in FileHandle structure
- FH_WRITEBUFPTR = $18 ; buffer pointer
- FH_WRITEBUFPOS = $1C ; current buffer position
- FH_WRITEBUFLEN = $20 ; total length of buffer, $1000
- FH_WRITESTARTPOS = $24 ; the file offset which corresponds to start of write buffer
- FH_DIRLISTSTART = $28 ; for directories, pointer on first item
- FH_FILENAME = $2C
-
-
- DEFAULT_WRITE_BUFSIZE = 2000 ; default 2ko bufferization for _Write
-
- OUTPUT_HANDLER_MAGIC = $DEAF1111
-
- BPTR2APTR:MACRO
- add.l \1,\1
- add.l \1,\1
- ENDM
-
- APTR2BPTR:MACRO
- lsr.l #2,\1
- ENDM
-
- DOSRTS:MACRO
- move.l D0,D1
- rts
- ENDM
-
- **************************************************************************
- * INITIALIZING *
- **************************************************************************
-
- DOSINIT move.l _dosbase,d0
- beq .init
- rts
-
- .init move.l #1050,d0 ;(reserved function)
- move.l #$46,d1
- lea _dosname,a0
- bsr _InitLibrary
- move.l d0,a0
- move.l d0,_dosbase
-
- patch _LVOParentDir(a0),_ParentDir ; requested by BS
- patch _LVOLoadSeg(a0),_LoadSeg
- patch _LVOUnLoadSeg(a0),DOSUNLOADSEG
- patch _LVOOpen(a0),_Open ; patched to BCPL
- patch _LVOOpenFromLock(a0),_OpenFromLock ; patched to BCPL
- patch _LVOClose(a0),_Close ; patched to BCPL
- patch _LVORead(a0),_Read ; patched to BCPL
- patch _LVOWrite(a0),_Write ; patched to BCPL
- patch _LVOSeek(a0),_Seek ; patched to BCPL
- patch _LVOLock(A0),_Lock ; patched to BCPL
- patch _LVOInput(A0),MYRTZ
- patch _LVODeleteFile(A0),_DeleteFile
- patch _LVOOutput(A0),_Output
- patch _LVODeviceProc(A0),MYRTZ
- patch _LVOGetProgramDir(A0),_GetProgramDir ; added by JOTD
- patch _LVOExamine(A0),_Examine ; patched to BCPL
- patch _LVOExNext(A0),_ExNext ; added by JOTD, patched to BCPL
- patch _LVOExamineFH(A0),_ExamineFH ; added by JOTD, patched to BCPL
- patch _LVOSetIoErr(A0),_SetIoErr ; added by JOTD
- patch _LVOIoErr(A0),_IoErr ; added by JOTD
- patch _LVOUnLock(A0),_UnLock ; patched to BCPL
- patch _LVOInfo(A0),_Info
- patch _LVODupLock(A0),_DupLock ; patched to BCPL
-
- patch _LVOIsInteractive(A0),_IsInteractive ; JOTD
- patch _LVOCheckSignal(A0),MYRTZ ; JOTD, dummy
- patch _LVOWaitForChar(A0),MYRTZ
- patch _LVOCurrentDir(A0),_CurrentDir
- patch _LVODelay(A0),_Delay ; added by JOTD
- patch _LVODateStamp(A0),DATESTAMP ; added by JOTD
- patch _LVOAssignPath(a0),ASSIGNPATH ; dummy
- patch _LVOAssignLock(a0),ASSIGNLOCK ; dummy
- patch _LVORunCommand(a0),RUNCOMMAND ; added by JOTD
- patch _LVOExecute(a0),EXECUTE ; added by JOTD
- patch _LVOGetArgStr(a0),GETARGSTR ; added by JOTD
- patch _LVOCreateProc(a0),CREATEPROC ; added by JOTD
-
- ; init rootnode
- move.l #_ROOTNODE,dl_Root(A0)
- rts
-
- _ROOTNODE:
- dc.l $EEEEEE01
- dc.l $EEEEEE02
- dc.l $0 ; datestamp
- dc.l $0
- dc.l $0
- dc.l $EEEEEE03
- _bcplcorrect6: ; corrected by exec init
- dc.l _DEFAULT_DOSINFO
- dc.l $EEEEEE04
- dc.l $EEEEEE05
- dc.l $EEEEEE06
- dc.l $EEEEEE07
- dc.l $EEEEEE08
- dc.l $EEEEEE09
- dc.l $EEEEEE0A ; to be continued...
-
- CNOP 0,4
-
- _DEFAULT_DOSINFO:
- dc.l $EEEEFFEE ; private
- _bcplcorrect7:
- dc.l _DEVLIST ; device list
- dc.l 0 ; leave to zero
- dc.l 0 ; leave to zero
-
- CNOP 0,4
-
- _DEVLIST:
- dc.l 0
- dc.l 0
- dc.l 0
- dc.l 0
- dc.l $EEEEEEEE ; normally BCPL pointer on BSTR "L:FastFileSystem"
- dc.l 1000 ; stack size
- dc.l 5 ; priority
- dc.l 0 ; startup
- dc.l $EEEEEE11
- dc.l $EEEEEE12
- _bcplcorrect8:
- dc.l _DEVNAME
-
- CNOP 0,4
- _DEVNAME:
- dc.b 3,"DH0",0 ; BSTR on device name + NULL termination
- CNOP 0,4
-
-
- **************************************************************************
- * PROGRAM EXECUTION *
- **************************************************************************
-
- ;<D1:NAME
- ;<D2:PRIORITY
- ;<D3:SEGLIST
- ;<D4:STACKSIZE
- ; this function never returns
- ;
- ; ATM this function is designed to handle
- ; autodetachable code, not for managing multiple tasks!!
-
- CREATEPROC:
- move.l #0,_EXECLIBTASK+172 ; now we're in the child process
-
- move.l D4,D0
- move.l #MEMF_CLEAR,D1
- bsr ForeignAllocMem
- tst.l D0
- beq .cpfail ; not enough mem for stack
-
- move.l D0,A7
- add.l D4,A7 ; sets new stack pointer
-
- LSL.L #2,D3 ; BCPL -> normal pointer
- MOVE.L D3,A1
- ADDQ.L #4,A1
-
- moveq.l #0,D0 ; I don't know why I'm doing this
- jmp (A1) ; executes the program
-
- .cpfail pea _LVOCreateProc
- pea _dosname
- bra _emufail
-
- ; EXECUTE
- ; <D1: program name
- ; <D2: input handler
- ; <D3: output handler
- ; >D0: success
-
- EXECUTE:
- move.l D1,A0
- lea .command(pc),A1
- .copy
- ; copy name until end or space
- move.b (A0)+,D0
- cmp.b #' ',D0
- bne.b .skipspc
- moveq.l #0,D0
- .skipspc
- move.b D0,(A1)+
- bne.b .copy
-
- ; now arguments
-
- lea .args(pc),A0
-
- tst.b (-1,A1)
- beq.b .lf
-
- .argcp
- move.b (A1)+,(A0)+
- bne.b .argcp
-
- .lf
- move.b #10,(A0)+ ; adds linefeed
- clr.b (A0)
-
- lea .command(pc),A1
- move.l A1,D1
- JSRLIB LoadSeg
- tst.l D0
- beq.b .err
-
- LSL.L #2,D0
- MOVE.L D0,A1
- ADDQ.L #4,A1
-
- lea .args(pc),A0
- moveq.l #0,D0
- .count
- tst.b (A0,D0.W)
- beq.b .exe
- addq.l #1,D0
- bra.b .count
-
- .exe
- JSR (A1)
- moveq.l #DOSTRUE,D0 ; success
- DOSRTS
- .err
- moveq.l #0,D0
- DOSRTS
-
- .command:
- blk.b $30,0
- .args:
- blk.b $40,0
-
- ;<D1:SEGLIST
- ;<D2:STACKSIZE
- ;<D3:ARGPTR
- ;<D4:ARGSIZE
-
- ;RUNCOMMAND will ignore STACKSIZE: it will use the current stack
-
- RUNCOMMAND:
- move.l D3,args_ptr
- ;; move.l D4,D0
-
- LSL.L #2,D1
- MOVE.L D1,A1
- ADDQ.L #4,A1
-
- jmp (A1) ; executes the program
-
- GETARGSTR:
- move.l args_ptr(pc),D0
- RTS
-
- args_ptr:
- dc.l 0
-
- _SetIoErr:
- move.l D1,last_io_error
- DOSRTS
-
- _IoErr:
- move.l last_io_error(pc),D0
- DOSRTS
-
- last_io_error:
- dc.l 0
-
- ; ******************************************
- ; 2 special macros added by JOTD for LoadSeg
-
- ; calls EnterDebugger when a condition is reached:
-
- BREAK_ON_COND:MACRO
- cmp.l \1,\2
- bne.b .ok\@
- bsr EnterDebugger
- nop
- nop
- .ok\@
- ENDM
-
- ; branch with call to EnterDebugger when true
- ; (to trap error code source)
-
- ; uncomment to activate
-
- ;BRANCH_COND:MACRO
- ; \1 .sk\@
- ; bra.b .end\@
- ;.sk\@
- ; bsr EnterDebugger
- ; bra \2
- ;.end\@
- ; ENDM
-
- BRANCH_COND:MACRO
- \1 \2 ; this is the non-debug configuration
- ENDM
-
- ;<D1: filename
- ;>D0: return code
-
- _DeleteFile:
- move.l D1,A0
- bsr SetCurrentDir
- move.l (_RESLOAD),a1
- jsr (resload_DeleteFile,a1)
- move.l D1,last_io_error ; stores error code
- DOSRTS
-
- ;>D1:FILENAME
- ;<D0:FIRST SEGMENT
- ;INTERNAL: D7-TOTAL # OF SEGMENTS
- ; D6-FILEHANDLE
- ; D5-SEGMENTBASE
- ; A4-8 BYTES SPACE ON STACK FOR HUNKHEADERS+other space for hunk overlay stuff
- ;LIMITATIONS: ONLY FOLLOWING HUNKS ALLOWED: HUNK_CODE, HUNK_DATA, HUNK_BSS,
- ; HUNK_END, HUNK_RELOC32, HUNK_HEADER, HUNK_DEBUG, HUNK_SYMBOL,
- ; HUNK_OVERLAY
- ; CONTACT IF YOU HAVE AN EXE WITH OTHER HUNKS, IM SIMPLY MISSING
- ; THE EXAMPLES TO IMPLEMENT THEM
-
- OVY_OVERLAYTABLE = 8
- OVY_HUNKTABLE = 12
- MAX_HUNK_NUMBER = 16
- LAST_LOADED_HUNK_NUMBER = 20
- FIRST_HUNK_NUMBER = 24
-
- _LoadSeg:
- MOVEM.L D2-D7/A2-A5,-(A7)
-
- ; allocates some memory from the stack
-
- SUB.L #FIRST_HUNK_NUMBER+4,A7
- MOVE.L A7,A4
-
- CLR.L (A4)+ ; not overlay ATM
- CLR.L (A4)+ ; not overlay load ATM
- CLR.L (A4)+
- CLR.L (A4)+
- CLR.L (A4)+
- MOVE.L A7,A4
-
- tst.l D1
- bne.b .normal_call
- ; undocumented LoadSeg() call to load the overlay part
- ; D1: NULL
- ; D2: BPTR on hunk table to complete
- ; D3: filehandle
-
- move.l D2,(OVY_HUNKTABLE,A4) ; save hunk table
- move.l D3,D0
- bra.b .read_header
-
- .normal_call
- move.l D1,A5 ; save filename
- MOVE.L #MODE_OLDFILE,D2
- BSR.W _Open
- TST.L D0
- BRANCH_COND BEQ.W,.ERR
-
- ; added by JOTD: copy command name & length
-
- lea _BCPL_CommandName,A3
- moveq.l #0,D1
- .strcp
- addq.l #1,D1
- move.b (A5)+,(A3,D1.W)
- beq.b .endcp
- bra.b .strcp
- .endcp
- lea _BCPL_CommandName,A3
- subq.l #1,D1
- move.b D1,(A3) ; store length
- ;
-
- .read_header:
- MOVE.L D0,D6 ; handler
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR2
- CMP.L #$3F3,(A4) ;FIRST LW=HUNK_HEADER?
- BRANCH_COND BNE.W,.ERR2
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR2
- TST.L (A4) ;NO NAME PLEASE (feature removed in OS2.0)
- BRANCH_COND BNE.W,.ERR2
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR2
- MOVE.L (A4),(MAX_HUNK_NUMBER,A4) ; highest hunk in file
-
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #8,D3
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR2
- MOVE.L (A4),(FIRST_HUNK_NUMBER,A4) ;0 but for overlays
- ; TST.L (A4) ;FIRST HUNK HAS TO BE 0
- ; BRANCH_COND BNE.W,.ERR2
-
- MOVE.L 4(A4),(LAST_LOADED_HUNK_NUMBER,A4) ;LAST LOADED HUNK (means: overlay not included)
-
- ; loop for all hunks which are to be loaded (don't consider overlays)
-
- move.l (LAST_LOADED_HUNK_NUMBER,A4),D7
- sub.l (FIRST_HUNK_NUMBER,A4),D7
-
- MOVEQ.L #0,D4 ;ALLOC MEM FOR ALL SEGMENTS
- MOVEQ.L #0,D5
- .1
-
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3 ;GET SIZE AND MEMFLAGS OF HUNK
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
-
- MOVE.L (A4),D0
-
- ; added by JOTD: check memtype requirement
-
- bsr .getmemflag ; >D1: MEMF_xxx
-
- ; compute mem size
-
- LSL.L #2,D0
- ADDQ.L #8,D0
- MOVE.L D0,D2 ;ALLOC MEM IN SIZE
- ADDQ.L #7,D0
- AND.L #$FFFFFFF8,D0
- BSR.W ForeignAllocMem
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
- MOVE.L D0,A3
- MOVE.L D2,(A3)
- CLR.L 4(A3)
-
- TST.L D4
- BNE.S .2
- MOVE.L D0,D5 ;D5-POINTER TO 1ST SEGMENT
- BRA.S .3
-
- .2
- MOVE.L D5,A3 ;POINTER TO 1ST SEGMENT
- .5 TST.L 4(A3)
- BEQ.S .4
- MOVE.L 4(A3),D2 ;NEXT SEGMENT
- LSL.L #2,D2
- SUBQ.L #4,D2
- MOVE.L D2,A3
- BRA.S .5
-
-
- .4 ADDQ.L #4,D0
- LSR.L #2,D0
- MOVE.L D0,4(A3)
- .3 ADDQ.L #1,D4
- CMP.L D7,D4
- BLS.S .1 ; next hunk
- ;HEADER COMPLETE, MEM ALLOCATED
-
- ;NOW PROCESSING THE HUNK_CODE, HUNK_DATA AND HUNK_BSS, HUNK_OVERLAY...
-
- move.l (MAX_HUNK_NUMBER,A4),D7 ; real hunk count (including overlays)
- sub.l (FIRST_HUNK_NUMBER,A4),D7 ; remove first hunk offset
- subq.l #1,D7
- bpl.s .d7positive
- moveq.l #0,D7
- .d7positive
-
- MOVEQ.L #0,D4
- .HN MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3 ;GET TYPE OF HUNK
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3 ;END OF FILE ENCOUNTERED
- .MAINHUNKS:
- AND.L #$3FFFFFFF,(A4)
- CMP.L #$3E9,(A4) ;HUNK_CODE?
- BEQ.W .HCD
- CMP.L #$3F1,(A4) ;HUNK_DEBUG?
- BEQ.S .HDEBUG1
- CMP.L #$3EA,(A4) ;HUNK_DATA?
- BEQ.S .HCD
- CMP.L #$3EB,(A4) ;HUNK_BSS?
- BEQ.S .HBSS
- CMP.L #$3F5,(A4) ;HUNK_OVERLAY?
- BEQ.W .HOVLY
- BRANCH_COND BRA.W,.ERR3
-
- ; debug hunk support, added by JOTD
- .HDEBUG1:
- bsr.s .HDEBUG
- BRA.W .HN
-
- .HDEBUG2
- bsr.s .HDEBUG
- bra .INNERHUNK
-
- .HDEBUG:
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3
- BSR.W _Read ;GET HUNK LENGTH
- MOVE.L (A4),D0
-
- BPTR2APTR D0
-
- MOVE.L D6,D1
- MOVE.L D0,D2
- MOVE.L #OFFSET_CURRENT,D3
- BSR.W _Seek ;SKIP DEBUG DATA
- CMP.L #-1,D0 ;error
- BRANCH_COND BEQ.W,.ERR3
- RTS
-
- .HBSS
- MOVE.L D6,D1 ;BSS-HUNK
- MOVE.L A4,D2
- MOVEQ.L #4,D3 ;IGNORE SIZE OF HUNK
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
- BRA.S .INNERHUNK
-
- .HCD
- MOVE.L D6,D1 ;CODE- AND DATA-HUNK
- MOVE.L A4,D2
- MOVEQ.L #4,D3 ;GET SIZE OF HUNK
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
- MOVE.L (A4),D3 ;LEN OF HUNK
- beq .INNERHUNK ; added by JOTD, hunk code can be of 0 length
- LSL.L #2,D3
- MOVE.L D4,D1 ;ACTUAL HUNK
- MOVE.L D5,A3 ;START OF 1ST SEGMENT
- BRA.S .HCD1
-
- .HCD2 MOVE.L 4(A3),D2
- LSL.L #2,D2
- SUBQ.L #4,D2
- MOVE.L D2,A3
- .HCD1 DBF D1,.HCD2
- MOVE.L A3,D2
- ADDQ.L #8,D2
- MOVE.L D6,D1
-
-
- move.l D2,-(A7) ; save D2
- BSR.W _Read
- move.l (A7)+,D2 ; restore D2
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
-
- ; OVERLAY? hunk code loaded:
- ; let's check if it's an overlay manager
-
- move.l D2,A0
- cmp.w #$6000,(A0)
- bne.b .INNERHUNK ; not an overlay manager
- cmp.l #$ABCD,(4,A0)
- bne.b .INNERHUNK ; not an overlay manager
-
- ; save overlay manager offset
-
- addq.l #8,A0
- move.l A0,(OVY_OVERLAYTABLE,A4)
-
- ; END OVERLAY?
- ; continue hunk processing
-
- .INNERHUNK:
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3 ;GET TYPE OF HUNK
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
- CMP.L #$3EC,(A4) ;HUNK_RELOC32?
- BEQ.S .HRELOCT
- CMP.L #$3F2,(A4) ;HUNK_END?
- BEQ.W .HENDT
- CMP.L #$3F0,(A4) ;HUNK_SYMBOL?
- BEQ.W .HSYMBOLT
- CMP.L #$3F1,(A4) ;HUNK_DEBUG?
- BEQ.W .HDEBUG2
- BRANCH_COND BRA.W,.ERR3
-
- .HRELOCT
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3 ;GET COUNT OF LW-RELOCS
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
- TST.L (A4) ;END OF RELOCATION?
- BEQ.S .INNERHUNK
- MOVE.L D6,D1
- MOVE.L A4,D2
- ADDQ.L #4,D2
- MOVEQ.L #4,D3 ;GET CORRESPONDING HUNK TO RELOCATE TO
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
-
- MOVE.L (A4),D0
-
- bsr .getmemflag
-
- LSL.L #2,D0 ;ALLOC MEM OF SIZE OF RELOCTABLE
- ADDQ.L #7,D0
- AND.L #$FFFFFFF8,D0
-
- BSR.W ForeignAllocMem
- TST.L D0
- BRANCH_COND BEQ.W,.ERR4
- MOVE.L D0,A2
- MOVE.L D6,D1
- MOVE.L A2,D2
- MOVE.L (A4),D3 ;GET CORRESPONDING RELOCS TO RELOCATE
- LSL.L #2,D3
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR4
- MOVE.L (A4),D3 ;# OF RELOCS
- MOVE.L 4(A4),D2 ;WHICH HUNK TO RELOCATE TO?
- MOVE.L D5,A0
- BRA.S .HRELOCT3
-
- .HRELOCT4
- MOVE.L 4(A0),D0
- LSL.L #2,D0
- SUBQ.L #4,D0
- MOVE.L D0,A0
- .HRELOCT3
- DBF D2,.HRELOCT4
-
- ADDQ.L #8,A0
- MOVE.L A0,D0 ;GOT THE HUNK TO RELOCATE TO
- LEA.L 8(A3),A1 ;THIS HUNK WILL BE RELOCATED
- MOVE.L A2,A0 ;HERE ARE THE RELOCS
- BRA.S .HRELOCT5
-
- .HRELOCT6
- MOVE.L (A0)+,D1
- ADD.L D0,(A1,D1.L)
- .HRELOCT5
- DBF D3,.HRELOCT6
- MOVE.L A2,A1 ;FREE THE MEM OF SIZE OF RELOCTABLE
- MOVE.L (A4),D0
- LSL.L #2,D0
- ADDQ.L #7,D0
- AND.L #$FFFFFFF8,D0
-
- bsr ForeignFreeMem
-
- BRA.W .HRELOCT
-
- .HSYMBOLT
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3
- BSR.W _Read ;GET NAMELENGTH
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3
- MOVE.L (A4),D0
- AND.L #$FFFFFF,D0
- BEQ.W .INNERHUNK ;IF NO NAMELENGTH -> END OF HUNK
- LSL.L #2,D0 ;LEN OF NAME IS IN LONGWORDS
- ADDQ.L #4,D0 ;SKIP ALSO SYMBOLOFFSET
- MOVE.L D6,D1
- MOVE.L D0,D2
- MOVE.L #OFFSET_CURRENT,D3
- BSR.W _Seek
- CMP.L #-1,D0
- BRANCH_COND BEQ.W,.ERR3
- BRA.S .HSYMBOLT
-
- ; overlay hunk support, added by JOTD
- .HOVLY:
- ; overlay file detected!
- ; fill in the information needed
-
- ; reads number of longwords - 1
-
- MOVE.L D6,D1
- MOVE.L A4,D2
- MOVEQ.L #4,D3 ;GET TYPE OF HUNK
- BSR.W _Read
- TST.L D0
- BRANCH_COND BEQ.W,.ERR3 ;END OF FILE ENCOUNTERED
- move.l (A4),D0 ;number of longwords that follow minus one
- addq.l #1,D0
-
- ; cmp.l #5,D0 ; too complex: not supported right now
- ; BRANCH_COND BNE.W,.ERR3
-
- add.l D0,D0
- add.l D0,D0
- move.l D0,D3 ; save size
- moveq.l #0,D1 ; any memory
-
- move.l A6,-(A7)
- move.l $4.W,A6
- JSRLIB AllocVec
- move.l (A7)+,A6
-
- move.l D0,D2 ; buffer
- beq.w .ERR3
-
- move.l (OVY_OVERLAYTABLE,A4),A0
- move.l D6,(A0) ; stream on executable file
- move.l D0,(4,A0) ; overlay table pointer
-
- ; D3: saved size
- move.l D2,D0
- MOVE.L D6,D1 ; handler
- BSR.W _Read ;LOAD LONGWORDS
-
- move.l (MAX_HUNK_NUMBER,A4),D0
- addq.l #1,D0
- add.l D0,D0
- add.l D0,D0
- moveq.l #0,D1 ; any memory
-
- move.l A6,-(A7)
- move.l $4.W,A6
- JSRLIB AllocVec
- move.l (A7)+,A6
-
- BRANCH_COND BEQ.W,.ERR3 ;no more mem!
-
- move.l (OVY_OVERLAYTABLE,A4),A0
- lsr.l #2,D0
- move.l D0,(8,A0) ; hunk table pointer, to fill in the end
- move.l #-1,($C,A0) ; invalid GlobalVec (unused by non-BCPL programs)
-
- ; stop file parsing from here, exit, without closing file
-
- bra.b .END_NOCLOSE
-
- .HENDT
- ADDQ.L #1,D4
- CMP.L D7,D4
- BLS.W .HN
-
- .END
- MOVE.L D6,D1
- BSR.W _Close
- .END_NOCLOSE
- MOVE.L D5,D0
- ADDQ.L #4,D0
- MOVE.L D0,OSM_LASTLOADSEG
- LSR.L #2,D0
- move.l D0,LastSegList ; added by JOTD
- move.l D0,LastSegList2 ; added by JOTD
-
- move.l (OVY_HUNKTABLE,A4),A0
- cmp.l #0,A0
- beq.b .tryovy
-
- ; just loaded an overlay hunk by the undocumented call to LoadSeg() with D1=0
- ; search for zero
-
- add.l A0,A0
- add.l A0,A0
- .zsearch
- tst.l (A0)+
- bne.b .zsearch
- .zfound:
- subq.l #4,A0
- bra.b .fillhunktable
-
- ; A0 points now to an empty space to fill in
-
- .tryovy:
- move.l (OVY_OVERLAYTABLE,A4),A0
- cmp.l #0,A0
- beq.b .noovy
-
- ; overlay: fill in the list with hunk list
-
- move.l (8,A0),D5
- add.l D5,D5
- add.l D5,D5
- move.l D5,A0 ; real pointer on seglist
- .fillhunktable:
- move.l D0,D5
- .hunkstrloop:
- move.l D5,(A0)+
- beq.b .noovy
- add.l D5,D5
- add.l D5,D5
- move.l D5,A1
- move.l (A1),D5
- bra.b .hunkstrloop
-
- .noovy
-
- ADD.L #FIRST_HUNK_NUMBER+4,A7 ; restores stack
- move.l (_RESLOAD),a2
- jsr (resload_FlushCache,a2) ; added by JOTD: cache flush
- .exit
- MOVEM.L (A7)+,D2-D7/A2-A5
- DOSRTS
-
- .ERR4
- .ERR3
- .ERR2
- pea _LVOLoadSeg
- pea _dosname
- bra _emufail
-
- ; MOVE.L D6,D1
- ; BSR.W _Close
- .ERR MOVEQ.L #0,D0
-
- ADDQ.L #8,A7
- bra.b .exit
-
- ; utility routines used by LoadSeg()
-
- .getmemflag:
- btst #HUNKB_CHIP,D0 ; CHIPMEM required?
- beq.b .nochip
-
- move.l #MEMF_CHIP,D1
- bra.b .doalloc
- .nochip
- btst #HUNKB_FAST,D0 ; FASTMEM required?
- beq.b .nofast
-
- move.l #MEMF_FAST,D1
- bra.b .doalloc
-
- .nofast
- MOVEQ.L #MEMF_ANY,D1 ;any memtype will do
- .doalloc
- bset #MEMB_CLEAR,D1 ;adds CLEAR flag
- rts
-
- ; UnLoadSeg()
-
- DOSUNLOADSEG
- MOVE.L A2,-(A7)
- LSL.L #2,D1
- .1 MOVE.L D1,A1
- MOVE.L (A1),D1
- LSL.L #2,D1
- MOVE.L D1,A2
-
- SUBQ.L #4,A1
- MOVE.L (A1),D0
-
- bsr ForeignFreeMem
-
- MOVE.L A2,D1
- BNE.S .1
-
- MOVEQ.L #0,D0
- MOVE.L (A7)+,A2
- DOSRTS
-
- **************************************************************************
- * I/O FILE FUNCTIONS *
- **************************************************************************
-
- ;will not work properly if the program assigns a subdir
- ;I (JOTD) added it for SlamTilt, which only assigns to PROGDIR:
- ;so it's OK
-
- ASSIGNLOCK:
- moveq.l #1,D0
- RTS
-
- ;will not work properly if the program assigns a subdir
- ;I (JOTD) added it for SlamTilt, which only assigns to PROGDIR:
- ;so it's OK
-
- ASSIGNPATH:
- moveq.l #1,D0
- RTS
-
- ; added by JOTD
-
- _GetProgramDir:
- lea .volname(pc),A1
- move.l D1,A1
- bsr _Lock
- RTS
- .volname:
- dc.b "PROGDIR:",0
- even
-
-
- ;Note: open strips the device from the filename (avoiding problems with assigns)
- ; < D1: filename
- ; < D2: openmode
- ; > D0: BPTR on filehandle
-
- _Open:
- MOVEM.L D4-D5/A3-A5,-(A7)
- MOVE.L D1,A3 ; filename
-
- cmp.b #'*',(A3)
- bne.b .nocon
- tst.b (1,A3)
- bne.b .nocon
- MOVEM.L (A7)+,D4-D5/A3-A5
- bra _Output
- .nocon
-
- MOVEQ.L #FH_FILENAME,D4 ;HEADERLEN
- TST.B (A3)
- BEQ.W .ERR
- .1 ADDQ.L #1,D4
- TST.B (A3)+
- BNE.S .1
- ADDQ.L #7,D4 ;NEXT $8-BOUNDARY
- AND.L #$FFFFFFF8,D4
- MOVE.L D1,D5 ;^NAME
- MOVE.L D4,D0 ;ALLOC. LENGTH
- MOVE.L #MEMF_CLEAR,D1 ;mem is better cleared
- BSR.W ForeignAllocMem
- TST.L D0
- BEQ.S .ERR
- MOVE.L D0,A3
- MOVE.L D4,FH_ALLOCLEN(A3) ;ALLOC. LENGTH
- MOVE.L D2,FH_OPENMODE(A3) ;OPENMODE
- CLR.L FH_CURRENTPOS(A3) ;INFILE-POINTER TO 0
- move.l #-1,FH_TYPE(A3) ;regular file
- ; for buffered write
- clr.l FH_WRITEBUFPTR(A3)
- clr.l FH_WRITEBUFPOS(A3)
- clr.l FH_WRITEBUFLEN(A3)
- clr.l FH_WRITESTARTPOS(A3)
-
- ; JOTD: cleaned up old Harry's devicename strip by calling my routine
-
- move.l D5,A0
- bsr SetCurrentDir
- lea FH_FILENAME(A3),A4
- .namecopy
- move.b (A0)+,(A4)+
- bne.b .namecopy
-
- CMP.W #MODE_NEWFILE,D2 ;IF MODE_NEWFILE, DELETE FILE
- BEQ.S .NEWFILE
-
- ;CHECK IF FILE EXISTS
- LEA.L FH_FILENAME(A3),A0 ;filename
- move.l _RESLOAD(PC),a1
- jsr (resload_GetFileSize,a1)
- MOVE.L D0,FH_FILELEN(A3)
- beq.b .filenotfound
-
- MOVE.L A3,D0
- .END
- APTR2BPTR D0 ; BCPL conversion (JOTD)
- MOVEM.L (A7)+,D4-D5/A3-A5
- DOSRTS
-
- .filenotfound
- ; sets DOS error code
- move.l #ERROR_OBJECT_NOT_FOUND,D1
- bsr _SetIoErr
-
- MOVE.L A3,A1
- MOVE.L FH_ALLOCLEN(A1),D0
-
- bsr ForeignFreeMem
-
- .ERR MOVEQ.L #0,D0
- BRA.S .END
-
- .NEWFILE ;REDUCE FILE TO 0 BYTE
- MOVE.L OSM_WRITE_BUFSIZE,D0
- MOVE.L #MEMF_CLEAR,D1
- BSR ForeignAllocMem
-
- move.l D0,FH_WRITEBUFPTR(A3)
- BEQ.B .NOBUFMEM
-
- ; buffered write, added by JOTD
-
- clr.l FH_WRITEBUFPOS(A3)
- move.l OSM_WRITE_BUFSIZE,FH_WRITEBUFLEN(A3)
- .NOBUFMEM
- CLR.L FH_FILELEN(A3)
- LEA.L FH_FILENAME(A3),A0
- MOVEQ.L #0,D0
- LEA.L $0.W,A1 ; address is not important since we write 0 bytes
-
- move.l _RESLOAD(pc),a5
- jsr (resload_SaveFile,a5)
-
- tst.l D0
- beq.b .saveok
-
- ; cause of the error
- move.l #ERROR_WRITE_PROTECTED,D1
- bsr _SetIoErr
- .saveok
-
- .SKIPZFILE
- MOVE.L A3,D0
- BRA.S .END
-
- ; fake output routine
-
- ; < D0: output file handler, actually a magic number
- ; that Write will recognize
-
- _Output:
- move.l #OUTPUT_HANDLER_MAGIC,D0
- DOSRTS
-
-
- ; < D1: file handler
- ; < D2: destination buffer
- ; < D3: number of bytes to read
- ; > D0: number of bytes read
-
- _Read:
- MOVEM.L D3/A2-A3,-(A7)
-
- BPTR2APTR D1
-
- MOVE.L D1,A3
- MOVE.L FH_CURRENTPOS(A3),D1 ;OFFSET (current)
- MOVE.L D2,A1 ;DEST
- LEA.L FH_FILENAME(A3),A0 ;NAME
- MOVE.L FH_FILELEN(A3),D0 ;TOTAL LENGTH OF FILE
- SUB.L D1,D0
- EXG D3,D0
- CMP.L D0,D3 ;CMP REQUESTED/REAL
- BHI.S .1 ;IF REQUESTED<=REAL
- MOVE.L D3,D0
- .1 MOVE.L D0,D3
- ;LOAD IT
- MOVE.L _RESLOAD(PC),A2
-
- JSR resload_LoadFileOffset(A2)
-
- ADD.L D3,FH_CURRENTPOS(A3)
- MOVE.L D3,D0
- MOVEM.L (A7)+,D3/A2-A3
- DOSRTS
-
- ; Write()
- ; <D1: filehandle
- ; <D2: source bytes
- ; <D3: length
- ;
- ; Jeff: added bufferized writes
-
- _Write:
- cmp.l #OUTPUT_HANDLER_MAGIC,D1 ; try to write to output?
- beq .fake_output
-
- ifeq 1
-
- MOVEM.L D3-D4/A2-A4,-(A7)
-
- BPTR2APTR D1
-
- MOVE.L D1,A3
- MOVE.L FH_CURRENTPOS(A3),D1 ;OFFSET
- MOVE.L D2,A1 ;SOURCE
- LEA.L FH_FILENAME(A3),A0 ;NAME
- MOVE.L D3,D0 ;LENGTH
-
- tst.l FH_WRITEBUFPTR(A3)
- beq.b .direct_write ; old write method
- ; don't write now, but store the data in the buffer
- ; for later use if we can
-
- move.l FH_WRITEBUFPOS(A3),D4
- add.l D0,D4 ; D4=next pos
-
- cmp.l FH_WRITEBUFLEN(A3),D4 ; compare buffer len with len to write
- bcc.b .buffer_overflow ; buffer will not hold all the data
-
- ; we don't really write the file here
- ; just copy it in the buffer
-
- tst.l FH_WRITEBUFPOS(A3)
- bne.b .filled
-
- ; the buffer is empty: store file offset
-
- move.l FH_CURRENTPOS(A3),FH_WRITESTARTPOS(A3)
- .filled
- ; ok, do the copy
-
- move.l A1,A2 ; source
- move.l FH_WRITEBUFPTR(A3),A4
- add.l FH_WRITEBUFPOS(A3),A4 ; destination
- move.l D0,D4 ; length
-
- ; perform the byte to byte copy
- .copy
- move.b (A2)+,(A4)+
- subq.l #1,D4
- bne.b .copy
-
- ; update the buffer position
-
- add.l D0,FH_WRITEBUFPOS(A3)
-
- ; goes to end of write
-
- bra.b .end_write
- .buffer_overflow
- ; buffer overflow. Can be improved
-
- ; first update buffer size (D1 holds offset)
-
- ; add.l FH_WRITEBUFPOS(A3),D1 ; update for WHDLoad call
- ; add.l FH_WRITEBUFPOS(A3),D3 ; update for size update
-
- ; second flush the buffer
-
- move.l A1,-(A7)
- move.l A3,A1
- bsr FlushWrite
- move.l (A7)+,A1
-
- ; then, direct write
-
- .direct_write
- MOVE.L _RESLOAD(PC),A2 ;SAVE IT
- JSR resload_SaveFileOffset(A2)
- .end_write
- ADD.L D3,FH_CURRENTPOS(A3)
- LEA.L FH_FILENAME(A3),A0 ;filename
- move.l _RESLOAD(PC),a1
- jsr (resload_GetFileSize,a1)
- MOVE.L D0,FH_FILELEN(A3)
- MOVE.L D3,D0
- MOVEM.L (A7)+,D3-D4/A2-A4
- DOSRTS
- endif
-
- ; JOTD: restored old non-bufferized version
-
- MOVEM.L D3-D4/A2-A3,-(A7)
-
- BPTR2APTR D1 ; APTR conversion (JOTD)
-
- MOVE.L D1,A3
- MOVE.L FH_CURRENTPOS(A3),D1 ;OFFSET
- MOVE.L D2,A1 ;DEST
- LEA.L FH_FILENAME(A3),A0 ;NAME
- MOVE.L D3,D0
-
- MOVE.L _RESLOAD(PC),A2 ;SAVE IT
- JSR resload_SaveFileOffset(A2)
- .SKIPWFILE:
- ADD.L D3,FH_CURRENTPOS(A3)
- LEA.L FH_FILENAME(A3),A0 ;filename
- move.l _RESLOAD(PC),a1
- jsr (resload_GetFileSize,a1)
- MOVE.L D0,FH_FILELEN(A3)
- MOVE.L D3,D0
- MOVEM.L (A7)+,D3-D4/A2-A3
- DOSRTS
-
- ; let the program believe that it wrote into the console
-
- .fake_output:
- move.l D3,D0 ; length written
- DOSRTS
-
- ; Kills write buffer (no more buffered write on this file)
- ; <A1: file handle
-
- BlockBufferedWrite:
- cmp.l #MODE_NEWFILE,FH_OPENMODE(A1)
- beq.b .killit
- rts
- .killit:
- movem.l D0-D1/A0-A1,-(A7)
-
- move.l FH_WRITEBUFPTR(A1),D0
- beq.b .exit ; no write buffer
-
- move.l D0,D1
- move.l FH_WRITEBUFLEN(A1),D0
- move.l D1,A1
-
- bsr ForeignFreeMem
-
- .exit:
- movem.l (A7)+,D0-D1/A0-A1
-
- clr.l FH_WRITEBUFPTR(A1)
- rts
-
- ;free allocated structure
- _Close:
- cmp.l #OUTPUT_HANDLER_MAGIC,D1
- beq _DOSCLOSEMAGIC
- tst.l D1
- beq _DOSCLOSENULL
- BPTR2APTR D1 ; APTR conversion (JOTD)
- move.l D1,A1
- APTR2BPTR D1 ; BCPL conversion (JOTD)
-
- move.l FH_WRITEBUFPTR(A1),D0
- beq.b _UnLock ; no write buffer
- bsr FlushWrite ; write flush just before closing
-
- move.l D1,-(A7)
- move.l D0,D1
- move.l FH_WRITEBUFLEN(A1),D0
- move.l D1,A1
-
- bsr ForeignFreeMem
-
- move.l (A7)+,D1
-
- _UnLock:
- tst.l D1
- beq _DOSCLOSENULL
-
- BPTR2APTR D1 ; APTR conversion (JOTD)
- MOVE.L D1,A1
- MOVE.L FH_ALLOCLEN(A1),D0
-
- bsr ForeignFreeMem
-
- moveq.l #DOSTRUE,D0
- DOSRTS
-
- _DOSCLOSENULL:
- moveq.l #0,D0
- DOSRTS
-
- _DOSCLOSEMAGIC:
- moveq.l #DOSTRUE,D0
- DOSRTS
-
- _Seek:
- BPTR2APTR D1 ; APTR conversion (JOTD)
- MOVE.L D1,A1
-
- ; some stuff for files opened in write mode
- ; (I don't think OSEmu handles Seek on write files but...)
-
- bsr FlushWrite ; will flush buffer if MODE_NEWFILE
- bsr BlockBufferedWrite ; no more buffered write
-
- CMP.L #OFFSET_BEGINNING,D3
- BEQ.S .BEGM
- CMP.L #OFFSET_END,D3
- BEQ.S .ENDM
- CMP.L #OFFSET_CURRENT,D3
- BEQ.S .CURM
- .ERR MOVEQ.L #-1,D0
- move.l #ERROR_SEEK_ERROR,D1
- bsr _SetIoErr
- .exit
- DOSRTS
-
- .CURM
- MOVE.L FH_CURRENTPOS(A1),D0
- MOVE.L D0,D1
- ADD.L D2,D1
- CMP.L FH_FILELEN(A1),D1
- BHI.S .ERR
- MOVE.L D1,FH_CURRENTPOS(A1)
- bra.b .exit
-
- .ENDM MOVE.L FH_CURRENTPOS(A1),D0
- MOVE.L FH_FILELEN(A1),D1
- ADD.L D2,D1
- CMP.L FH_FILELEN(A1),D1
- BHI.S .ERR
- MOVE.L D1,FH_CURRENTPOS(A1)
- bra.b .exit
-
- .BEGM MOVE.L FH_CURRENTPOS(A1),D0
- MOVE.L D2,D1
- CMP.L FH_FILELEN(A1),D1
- BHI.S .ERR
- MOVE.L D1,FH_CURRENTPOS(A1)
- bra.b .exit
-
- ; internal buffer flush
- ; <A1: filehandle pointer
-
- FlushWrite:
- cmp.l #MODE_NEWFILE,FH_OPENMODE(A1)
- bne.b .noflush
-
- movem.l D0-A6,-(A7)
- move.l A1,A3 ; filehandle
-
- move.l FH_WRITEBUFPOS(A3),D0 ; length
- beq.b .end ; 0 length no need to flush
-
- LEA.L FH_FILENAME(A3),A0 ; name
- MOVE.L FH_WRITEBUFPTR(A3),A1 ; buffer
- MOVE.L FH_WRITESTARTPOS(A3),D1 ; offset
-
- ; resets bufferization parameters
-
- clr.l FH_WRITEBUFPOS(A3)
- clr.l FH_WRITESTARTPOS(A3)
-
- ; write the file chunk
-
- move.l _RESLOAD(pc),a5
- jsr (resload_SaveFileOffset,a5)
-
- .end
- movem.l (A7)+,D0-A6
- .noflush
- rts
-
- ; Added by JOTD. Now Flashback works
- ; <D2: info structure to fill in
- ; >D0: TRUE if success (which is always the case)
-
- _Info:
- movem.l A1,-(A7)
- move.l D2,A1
-
- move.l #0,(id_NumSoftErrors,A1) ; no errors!
- move.l #0,(id_UnitNumber,A1) ; unit 0 should be OK
- move.l #ID_VALIDATED,(id_DiskState,A1) ; disk validated
- move.l #10000,(id_NumBlocks,A1) ; number of blocks = 500 Megs
- move.l #ID_DOS_DISK,(id_DiskType,A1) ; disk type: OFS
- move.l #0,(id_VolumeNode,A1) ; zero this entry. it sucks but...
- move.l #0,(id_InUse,A1) ; not in use
-
- movem.l (A7)+,A1
- moveq.l #DOSTRUE,D0 ; returns TRUE (success)
- DOSRTS
-
- _Delay: ; added by JOTD
- tst.l D1
- beq.b .exit
- .loop
- bsr _waitvb
- subq.l #1,D1
- bne.b .loop
- .exit
- rts
-
- ; make as if the clock was not set
-
- DATESTAMP:
- move.l D1,A0
- clr.l (A0)+
- clr.l (A0)+
- clr.l (A0)
- move.l D1,D0
- rts
-
- **************************************************************************
- * FILE MANAGEMENT FUNCTIONS *
- **************************************************************************
-
- ;filehandle represents the following structure (do not try to access it!):
- ;0-allocated len
- ;4-total filelength
- ;8-pointer in file
- ;$c-openmodus
- ;$10-filename
-
- ;if $10 of filehandle is a : its the volumelock
- ;atm: 0.L-$1000 len, 4.W-# of file in examine/exnext (-1:invalid),
- ;6.W-MAX# OF FILES, 8.L-pointer in table, $c.L-openmode
-
- _Lock:
- MOVEM.L D4-D5/A2-A5,-(A7)
- MOVE.L D1,A3
- MOVE.L #FH_FILENAME,D4 ;HEADERLEN
- TST.B (A3)
- BEQ.B .ERR ; empty filename, error
- .1 ADDQ.L #1,D4
- TST.B (A3)+
- BNE.S .1
- ADDQ.L #7,D4 ;NEXT $8-BOUNDARY
- AND.L #$FFFFFFF8,D4
- MOVE.L D1,D5 ;^NAME
- MOVE.L D4,D0 ;ALLOC. LENGTH
- MOVE.L #MEMF_CLEAR,D1
- BSR.W ForeignAllocMem
- TST.L D0
- BEQ.S .ERR
-
- MOVE.L D0,A3
- MOVE.L D4,FH_ALLOCLEN(A3) ;ALLOC. LENGTH
- MOVE.L D2,FH_OPENMODE(A3) ;OPENMODE
- CLR.L FH_CURRENTPOS(A3) ;INFILE-POINTER TO 0
-
- ; JOTD: devicename strip cleaned up
-
- move.l D5,A0
- bsr SetCurrentDir
- lea FH_FILENAME(A3),A4
- .namecopy
- move.b (A0)+,(A4)+
- bne.b .namecopy
-
- lea FH_FILENAME(A3),A4
- tst.b (A4)
- beq.b .VOLUMELOCK ; lock root directory
-
-
- ;--------------------------------------------------
- IFD HARRYOLDCODE
- LEA.L FH_FILENAME(A3),A4 ;TRANS FILENAME
- MOVE.L D5,A5
- .2 MOVE.B (A5)+,(A4) ; remove the volume name
- BEQ.S .4
- CMP.B #':',(A4)
- BNE.S .3
-
- TST.B (A5)
- BEQ.S .VOLUMELOCK ; lock root directory
-
- LEA.L FH_FILENAME-1(A3),A4
- .3 ADDQ.W #1,A4
- BRA.S .2
- .4
- ENDC
- ;--------------------------------------------------
-
-
- ;CHECK IF FILE EXISTS
- ;(we need to know if we locked a file or a directory)
- ;due to WHDLoad limitations, we've got to work around
- ;the directory existence test problem
-
- LEA.L FH_FILENAME(A3),A0 ;filename
- move.l _RESLOAD(PC),a1
- jsr (resload_GetFileSize,a1)
- MOVE.L D0,FH_FILELEN(A3)
-
- TST.L D0
- BEQ.S .TRYDIR ;GetFileSize failed, maybe it's a directory...
- MOVE.L A3,D0
- .END
- MOVEM.L (A7)+,D4-D5/A2-A5
- APTR2BPTR D0 ; BCPL conversion (JOTD)
- DOSRTS
-
- .ERR MOVEQ.L #0,D0
- BRA.S .END
-
- ; directory locked: rootdir locked
-
- .VOLUMELOCK
- MOVE.L FH_ALLOCLEN(A3),D0 ;free mem because we need a larger area
- MOVE.L A3,A1 ; JOTD: bugfix: changed D1 to A1
-
- bsr ForeignFreeMem
-
- MOVE.L #$1000,D0
- MOVE.L #MEMF_CLEAR,D1 ; MEMF_CHIP removed
- BSR.W ForeignAllocMem
- TST.L D0
- BEQ.W .ERR
- MOVE.L D0,A3
- ;; MOVE.B #':',FH_FILENAME(A3) ; addressing error bug: ':' instead of #':'
- CLR.B FH_FILENAME(A3) ; addressing error bug: ':' instead of #':'
- MOVE.L D2,FH_OPENMODE(A3)
- MOVE.W #-2,FH_FILELEN(A3) ; directory
- ;8(A3) is already clear due MEMF_CLEAR
- MOVE.L #$1000,FH_ALLOCLEN(A3)
- BRA.W .END
-
- .TRYDIR:
- LEA.L FH_FILENAME(A3),A0 ;filename
- move.l _RESLOAD(PC),a2
- lea .smallbuf(pc),A1
- moveq.l #4,D0 ; small buffer
- jsr (resload_ListFiles,a2)
-
- tst.l D1
- BNE.S .LOCKFAILED ; directory not found
-
- ; directory found here
-
- MOVE.L FH_ALLOCLEN(A3),D0 ;free mem because we need a larger area
- MOVE.L A3,A1 ; JOTD: bugfix: changed D1 to A1
-
- bsr ForeignFreeMem
-
- MOVE.L #$1000,D0
- MOVE.L #MEMF_CLEAR,D1 ; MEMF_CHIP removed
- BSR.W ForeignAllocMem
- TST.L D0
- BEQ.S .ERR
- MOVE.L D0,A3
-
- ; copy directory name
-
- lea FH_FILENAME(A3),A5
- move.l A0,A4 ; save A0
-
- move.l D5,A0
- bsr SetCurrentDir
- .copy
- move.b (A0)+,(A5)+
- bne.b .copy
-
- move.l A4,A0 ; restore A0
-
- MOVE.L D2,FH_OPENMODE(A3)
- MOVE.W #-2,FH_FILELEN(A3) ; -2 for directory
-
- ;8(A3) is already clear due MEMF_CLEAR
- MOVE.L #$1000,FH_ALLOCLEN(A3)
- BRA.W .END
-
- .smallbuf:
- blk.l 10,0
-
- .LOCKFAILED
- MOVEQ.L #0,D0
- ; sets IoErr()
- move.l #ERROR_DIR_NOT_FOUND,D1
- BSR _SetIoErr
- .FREEMEM
- MOVE.L D0,D5
- MOVE.L FH_ALLOCLEN(A3),D0
- MOVE.L A3,A1 ; bugfix there too
-
- bsr ForeignFreeMem
-
- MOVE.L D5,D0
- BRA.W .END
-
- ; OpenFromLock() acts just as DupLock(), but I will have to change this
- ; when we change filehandle structure to match the real one
- ; < D1: lock
- ; > D0: lock copy
-
- _OpenFromLock:
-
- _DupLock:
- TST.L D1
- BEQ.S .ROOTLOCK
-
- BPTR2APTR D1
-
- MOVE.L D1,-(A7)
- MOVE.L D1,A0
- MOVE.L FH_ALLOCLEN(A0),D0
- MOVE.L #MEMF_CLEAR,D1
- BSR.W ForeignAllocMem
- MOVE.L (A7)+,A0
- TST.L D0
- BEQ.S .ERR
- MOVE.L D0,A1
- MOVE.L FH_ALLOCLEN(A0),D1
- SUBQ.L #1,D1
- .1 MOVE.B (A0)+,(A1)+
- DBF D1,.1
- .EXIT
- APTR2BPTR D0
- DOSRTS
-
- .ERR MOVEQ.L #0,D0
- DOSRTS
-
- ; duplicate from no source
-
- .ROOTLOCK
- MOVE.L #FH_FILENAME+10,D0
- MOVE.L #MEMF_CLEAR,D1
- BSR.W ForeignAllocMem
- TST.L D0
- BEQ.S .ERR
- MOVE.L D0,A0
- MOVE.L #FH_FILENAME+10,FH_ALLOCLEN(A0)
- move.l #-2,FH_FILELEN(A1) ; directory
- bra.b .EXIT
-
- ; Examine next directory entry
- ; < D1: lock
-
- _ExNext:
- MOVEM.L A2-A3,-(A7)
- BPTR2APTR D1
-
- move.l D1,A3
- move.l FH_CURRENTPOS(A3),A2
- tst.b (A2)
- beq.b .nomorefiles
- bsr ExamineOneFile
- moveq.l #DOSTRUE,D0 ; ok
- .exit
- MOVEM.L (A7)+,A2-A3
- DOSRTS
-
- .nomorefiles
- move.l #ERROR_NO_MORE_ENTRIES,last_io_error ; not really an error...
- moveq.l #0,D0
- bra.b .exit
-
- ; < A3: filehandle
- ; > D0: 0 if OK, -1 if error
-
- ExamineOneFile:
- move.l FH_CURRENTPOS(A3),A1 ; current file pointer
- lea FH_FILENAME(A3),A0 ; current directory lock name
-
- lea .temp_buffer(pc),A2
- bsr _ADDPART
-
- lea .temp_buffer(pc),A0
- MOVE.L _RESLOAD(PC),A2
- jsr (resload_GetFileSize,a2)
- ADDQ.L #1,FH_FILELEN(A3) ; 1 more file
- MOVE.L D2,A2 ; FIB
-
- TST.L D0
- BNE.W .isfile ; don't care about the errors (dir)
- MOVE.L #ST_USERDIR,fib_DirEntryType(A2) ; directory
- MOVE.L #ST_USERDIR,fib_EntryType(A2) ; directory
- bra.b .fillname
- .isfile
-
- MOVE.L D0,fib_Size(A2)
- MOVE.L #2,(A2)
- MOVE.L #ST_FILE,fib_DirEntryType(A2) ; regular file
- MOVE.L #ST_FILE,fib_EntryType(A2) ; regular file
- SUBQ.L #1,D0
- LSR.L #8,D0 ;ASSUMED FFS
- LSR.L #1,D0
- ; DIVU #$1E8,D0 ;WOULD BE OFS
- ADDQ.L #1,D0
- MOVE.L D0,fib_NumBlocks(A2)
- .fillname:
- move.l FH_CURRENTPOS(A3),A0 ; current file pointer
- LEA.L fib_FileName(A2),A1
- .COPYFILENAME2
- MOVE.B (A0)+,(A1)+
- TST.B -1(A0)
- BNE.S .COPYFILENAME2
-
- MOVE.L A0,FH_CURRENTPOS(A3) ; UPDATE FILENAME POINTER
- moveq.l #0,D0 ; was OK
- RTS
- .ERR
- MOVEQ.L #-1,D0
- rts
- .temp_buffer:
- blk.b 256,0
-
- ; added by JOTD, utility function,
- ; could be plugged to the read AddPart
- ; if anyone needs it
-
- ; < A0: dirname
- ; < A1: filename
- ; > A2: dirname/filename
-
- _ADDPART:
- movem.l A0-A2,-(A7)
- clr.b (A2)
-
- tst.b (A0)
- beq.b .cp_filename ; no dirname
-
- .cp_dirname
- move.b (A0)+,(A2)+
- bne.b .cp_dirname
-
- subq.l #1,A2
-
- cmp.b #'/',(-1,A2) ; ends by /
- beq.b .cp_filename
-
- move.b #'/',(A2)+
-
- .cp_filename
- move.b (A1)+,(A2)+
- bne.b .cp_filename
-
- movem.l (A7)+,A0-A2
- RTS
-
- ; < D1: lock
- ; < D2: file info block
-
- _Examine:
- MOVEM.L A2-A3,-(A7)
-
- BPTR2APTR D1
-
- MOVE.L D1,A3
-
- cmp.w #-2,FH_FILELEN(A3)
- bne.b .ONEFILE
-
- .DIRECTORY:
- .VOLUME:
- ; volume (current dir)/dir lock
- ; skip the directory name
-
- LEA.L FH_FILENAME(A3),A2
- .zerohunt
- tst.b (A2)+
- bne.b .zerohunt
- move.l A2,FH_DIRLISTSTART(A3)
- LEA.L FH_FILENAME(A3),A1
- move.l A2,A4
- sub.l A1,A4
-
- ; clear the filelist zone
-
- MOVE.L #$1000-FH_FILENAME-1,D0
- sub.l A4,D0
- move.l D0,D1 ; save buffer length
- .CLR1 CLR.B (A2)+
- DBF D0,.CLR1
-
- MOVE.L D1,D0 ; buffer max length
- LEA.L FH_FILENAME(A3),A0 ; GET FILEDIR
- MOVE.L FH_DIRLISTSTART(A3),A1 ; buffer
- move.l _RESLOAD(pc),a2
-
- jsr (resload_ListFiles,a2)
-
- TST.W D0
- BEQ.W .ERR
-
- MOVE.L FH_DIRLISTSTART(A3),FH_CURRENTPOS(A3) ; init file pointer with first file of dir
-
- ; fill file info block structure fields (dir type, name)
-
- move.l D2,A0
- move.l #ST_USERDIR,fib_DirEntryType(A0) ; directory
- move.l #ST_USERDIR,fib_EntryType(A0) ; directory
- LEA fib_FileName(A0),A1 ; copy name
- LEA FH_FILENAME(A3),A0
- .COPYFILENAME2
- MOVE.B (A0)+,(A1)+
- ;; TST.B -1(A0) ; JOTD: useless
- BNE.S .COPYFILENAME2
-
- MOVEM.L (A7)+,A2-A3
- RTS
-
-
- .ONEFILE
- lea FH_FILENAME(A3),a0 ;filename
- move.l _RESLOAD(PC),a2
- jsr (resload_GetFileSize,a2)
- TST.L D0
- BEQ.S .ERR
- MOVE.L D2,A2
- MOVE.L D0,fib_Size(A2)
- MOVE.L #2,(A2)
- MOVE.L #ST_FILE,fib_DirEntryType(A2)
- MOVE.L #ST_FILE,fib_EntryType(A2) ; added by JOTD, Sensible Soccer CD32 v1.2
- MOVE.L #$F0,fib_Protection(A2) ; added by JOTD, File rwxd
- LSR.L #8,D0 ;ASSUMED FFS
- LSR.L #1,D0
- ; DIVU #$1E8,D0 ;WOULD BE OFS
- ADDQ.L #1,D0
- MOVE.L D0,fib_NumBlocks(A2)
- LEA.L FH_FILENAME(A3),A0
- LEA.L fib_FileName(A2),A1
- .COPYFILENAME
- MOVE.B (A0)+,(A1)+
- ;; TST.B -1(A0) ; JOTD: useless
- BNE.S .COPYFILENAME
- MOVEQ.L #DOSTRUE,D0
- MOVEM.L (A7)+,A2-A3
- RTS
-
- .ERR pea _LVOExamine
- pea _dosname
- bra _emufail
-
- ; Computes basename from full name (JOTD)
- ; < A0: name
- ; > A0: name's file part
- ; kind of strrchr with '/' char
- ; unused at the moment, but works
- ifeq 1
- BaseName:
- movem.l D0,-(A7)
- ; first count string length
- moveq.l #0,D0
- .loop1
- tst.b (A0,D0.L)
- beq.b .countend
- addq.l #1,D0
- bra.b .loop1
- .countend
-
- .loop2
- cmp.b #'/',(A0,D0.L)
- beq.b .found
- cmp.b #':',(A0,D0.L)
- beq.b .found
- dbf D0,.loop2
- bra.b .exit
- .found
- lea 1(A0,D0.L),A0
- .exit
- movem.l (A7)+,D0
- rts
- endif
-
- ; < A0: name
- ; > A0: name with current dir added
-
- SetCurrentDir:
- movem.l A3,-(A7)
-
- move.l $4.W,A3
- move.l ThisTask(A3),A3
- tst.l pr_CurrentDir(A3)
- beq.b .end ; no need to append path
-
- ; the directory was changed
- ; we need to check if the path is relative or
- ; absolute
-
- movem.l D0-D1/A0-A2,-(A7)
- moveq.l #0,D0
- .colonloop
- tst.b (A0,D0.L)
- beq.b .relative ; colon not found: relative path
- cmp.b #':',(A0,D0.L)
- beq.b .absolute
- addq.l #1,D0
- bra.b .colonloop
- .relative
- ; this is untested!
-
- ; add the current dirname at start
-
- move.l pr_CurrentDir(A3),D0
- BPTR2APTR D0 ; converts to APTR
- move.l A0,A1 ; filename
- move.l D0,A0
- lea (FH_FILENAME,A0),A0 ; directory name
- lea .namebuffer(pc),A2
- bsr _ADDPART
- move.l A2,8(A7) ; will be in A0 when registers are restored
- .absolute: ; absolute path, the current directory has no effect
- movem.l (A7)+,D0-D1/A0-A2
- .end:
- bsr RemoveColonFromName
- movem.l (A7)+,A3
- rts
-
- .namebuffer:
- blk.b 256,0
-
- ; Removes volumename: prefix if any (only changes pointer)
- ; < A0: name
- ; > A0: name without colon
- ; kind of strchr with ':' char
-
- RemoveColonFromName:
- movem.l D0/A1,-(A7)
- move.l A0,A1 ; save A0
- .loop
- move.b (A0)+,D0
- beq.b .endofstring
- cmp.b #':',D0
- bne.b .loop
- .exit
- movem.l (A7)+,D0/A1
- rts
-
- ; colon was not found: restore original string
-
- .endofstring:
- move.l A1,A0 ; original A0
- bra.b .exit
-
- ; added by JOTD (needed by SlamTilt)
-
- _ExamineFH:
- MOVEM.L D3/A3,-(A7)
-
- BPTR2APTR D1
-
- MOVE.L D1,A3
- MOVE.L D2,D3 ;output struct
- LEA.L FH_FILENAME(A3),A0 ;NAME
- move.l A0,D1
- move.l #MODE_OLDFILE,D2
- bsr _Open
- move.l D0,-(A7)
-
- move.l D3,D2
- move.l D0,D1 ;filehandle!
- bsr _Examine
-
- move.l (A7)+,D1
- bsr _Close
-
- MOVEM.L (A7)+,D3/A3
- RTS
-
- _IsInteractive:
- moveq #0,D0
- cmp.l #OUTPUT_HANDLER_MAGIC,D1
- bne.b .noint
- moveq #DOSTRUE,D0 ; interactive
- .noint
- rts
-
- ; CurrentDir
- ; < D1: new dirlock
- ; > D0: old dirlock
-
- _CurrentDir:
- movem.l D2/A2/A6,-(A7)
- move.l D1,D2
-
- sub.l A1,A1
- move.l $4.W,A6
- JSRLIB FindTask ; find ourselves
- move.l D0,A2
- move.l pr_CurrentDir(A2),D0 ; old lock to return
-
- tst.l D2
- beq.b .root ; NULL lock: root directory
-
- move.l D2,A0 ; save dir pointer
- BPTR2APTR D2 ; APTR conversion
-
- ; check if it's a file: Cruise For A Corpse tries
- ; to CurrentDir() with a file lock!
-
- move.l D2,A1
- tst.l FH_FILELEN(A1)
- bpl.b .file
-
- ; it's a directory: ok to change lock
-
- move.l A0,D2 ; restore BPTR lock
- .root
- move.l D2,pr_CurrentDir(A2) ; sets new dirlock as current directory
- .file
- movem.l (A7)+,D2/A2/A6
- DOSRTS
-
- ; < D1: lock
- ; > D0: lock of parent or NULL
-
- _ParentDir:
- ; first duplicates the lock
-
- bsr _DupLock
-
- move.l D0,A1
- BPTR2APTR A1
- lea FH_FILENAME(A1),A1 ; pointer on filename
- move.l A1,A0
- .loop1
- tst.b (A0)+
- bne.b .loop1
- ; reached end of filename, now reverse to find first '/' in name
-
- .loop2
- cmp.b #'/',-(A0)
- beq.b .slashfound
- cmp.l A0,A1
- bne.b .loop2
-
- ; met start of filename: parent not found: returns lock on root path
- ; (should return NULL but...)
-
- move.l D0,A1
- BPTR2APTR A1
- lea FH_FILENAME(A1),A1 ; pointer on filename
- move.b #':',(A1)+
- clr.b (A1)
- bra.b .out
-
- .slashfound
- ; slash found: replaces by 0
-
- clr.b (A0)
-
- ; returns new lock
-
- .out
- DOSRTS
-